home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 14228 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  4.2 KB

  1. Path: locutus.rchland.ibm.com!usenet
  2. From: Philip Staite <pstaite+@rchland.ibm.com>
  3. Newsgroups: comp.lang.c++
  4. Subject: Re: Special sort algorithm
  5. Date: Fri, 29 Mar 1996 09:21:22 -0600
  6. Organization: IBM Rochester, MN
  7. Message-ID: <315BFFF2.167E@rchland.ibm.com>
  8. References: <31593E09.29A0@kmd.dk>
  9. NNTP-Posting-Host: powertool.rchland.ibm.com
  10. Mime-Version: 1.0
  11. Content-Type: text/plain; charset=us-ascii
  12. Content-Transfer-Encoding: 7bit
  13. X-Mailer: Mozilla 2.01 (X11; I; AIX 1)
  14.  
  15. Carsten Bonde wrote:
  16. > Hi
  17. > This is not strictly related to C++, but I guess some of you may have a hint
  18. > on this anyway.
  19. > I am trying to make a DOS file sorting program, which is to be part of a commercial product.
  20. > It must :
  21. >  - Sort big files of short lines
  22. >    lines are uneven length
  23. >    files are XX MB
  24. >    lines are < 100 chars
  25. >  - Put resulting file in original file
  26. >  - Run in very little memory ( < 50 K)
  27. >  - Use about no extra disk space ( < 10% extra)
  28. >  - Run reasonably fast
  29. > I have tried implementing in-file bubblesort and others with the language
  30. > being C++. But they are way too slow, even with some optimizing buffers.
  31. > Does anyone have a suggestion for a good algorithm, or maybe even source.
  32.  
  33. Try this approach.  Although it won't be blindingly fast, it should get
  34. the job done...  Note, if you could relax the disk space requirements to
  35. allow for 2x disk storage (ie. 100% extra) then you could use a
  36. conventional external merge sort and it'd run pretty fast.  Come on,
  37. disk space is cheap, an extra 50M of disk could improve speed by an
  38. order of magnitude here...
  39.  
  40. Anyway, consider this algorithm:
  41.  
  42. 1) Break up the initial file into < 20K sections.  To do this, stat() or
  43. fstat() the file for total length.  Subtrackt 20K from that, seek to
  44. that position, then move fwd to the first newline.  Remember this
  45. position.  Copy the remainder of the file to a temp disk file.  Use
  46. truncate() or ftruncate() to chop the original file's size. (lopping off
  47. the chunk just saved to the temp file)  Repeat this until original file
  48. has been diced into N files of 20K or less.  This shouldn't require more
  49. than 20K over the initial file size.
  50.  
  51. 2) Block bubble sort.  Read two of the temp files into a 40K buffer.
  52. Perform a quicksort on this buffer. (see qsort)  There should be
  53. approximately 400 lines in the buffer.
  54.  
  55. 3) Keep the first 200 lines in the buffer, write the "last" 200 (or
  56. less) back to the last file read.
  57.  
  58. 4) Read the "next" file into the slots in the 40K buffer just flushed to
  59. the file.
  60.  
  61. 5) Perform quicksort again.
  62.  
  63. 6) Repeat steps 3, 4, and 5 until there is no "next" file.
  64.  
  65. 7) Now, these first 200 lines are guaranteed to be the first 200 lines
  66. in the whole data set.  Write these to the original file.
  67.  
  68. 8) Copy the "last" temp file to the first, delete the last.
  69.  
  70. 9) Repeat steps 2-6 to get the next 200 lines in the file.
  71.  
  72. 10) Append these 200 lines to the original file.
  73.  
  74. 11) Repeat steps 8-10 until there are no more temp files.
  75.  
  76.  
  77. What this is really doing is partitioning the original file into 20K
  78. segments.  Then performing a bubble sort on the segments where two at a
  79. time are brought into memory to compare. (external bubble, ugh...)
  80.  
  81. Potential problems with this....
  82.  
  83. When you run qsort it may pick a really bad pivot element.  After the
  84. first pass, each "half" of the buffer is partially sorted.  Therefore if
  85. qsort arbitrarily picks the middle element it'll actually get a pivot
  86. that is offset well into the sorted array.  May want to adjust your
  87. buffer size to 15K and maintain a 15K buffer and a 30K buffer.  This way
  88. you would only have to do an initial qsort on the unsorted parts (say,
  89. as you partitioned the original file).  Thereafter, you would just
  90. perform an internal merge of the "held" 15K and the 15K comming in from
  91. a temp file.
  92.  
  93. This may generate a LOT of files.  If the original file is 50M and you
  94. partition it into 20K files that is 2500 files.  DOS is ill-equipped to
  95. deal with that many files.  That is 80K of directory entries alone on
  96. disk.  Note, DOS doesn't recover directory space when the files are
  97. deleted, so you'll want to make sure you do this in a temp direcotory
  98. then remove the directory to recover that 80K...
  99.  
  100.  
  101. -- 
  102.  
  103. Phil Staite, (507) 253-2529, team OS/2
  104. internet: pstaite@vnet.ibm.com  internal: pstaite@rchland
  105.